import {
  MiddlewareConsumer,
  Module,
  NestModule,
  RequestMethod,
} from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { ServeStaticModule } from '@nestjs/serve-static';
import type { RedisClientOptions } from 'redis';
import { CacheModule } from '@nestjs/cache-manager';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AccessMiddleware } from '@/core/middlewares/access.middleware';
import { UserModule } from '@/modules/user/user.module';
import {
  AppService,
  buildTypeormModuleConfig,
  buildCacheModuleConfig,
  buildServeStaticConfig,
} from '@/app.service';
import { SharedModule } from '@/modules/shared/shared.module';
import { ScheduleModule } from '@/modules/schedule/schedule.module';
import { AuthModule } from '@/modules/auth/auth.module';
import { DbModule } from '@/db/db.module';
import { JetbrainsModule } from '@/modules/jetbrains/jetbrains.module';

@Module({
  imports: [
    ConfigModule.forRoot({ isGlobal: true }),
    TypeOrmModule.forRootAsync(buildTypeormModuleConfig()),
    CacheModule.registerAsync<RedisClientOptions>(buildCacheModuleConfig()),
    ServeStaticModule.forRootAsync(buildServeStaticConfig()),
    DbModule,
    UserModule,
    SharedModule,
    ScheduleModule,
    AuthModule,
    JetbrainsModule,
  ],
  providers: [AppService],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(...[AccessMiddleware])
      .forRoutes({ path: '*', method: RequestMethod.ALL });
  }
}
